﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using Moq;
using NUnit.Framework;
using TeamsPortal.DataAccess;
using TeamsPortal.ServiceClient;
using TeamsPortal.Tests.Fakes;
using TeamsPortal.Web.Controllers;

namespace TeamsPortal.Tests.Controllers
{
	[TestFixture]
	public class MessagesControllerTest
	{
		[Test]
		public void ListFlagged()
		{
            var mockMessageServiceClient = new Mock<IMessagesServiceClient>();
            mockMessageServiceClient
                .Setup(m => m.ListFlagged())
                .Returns(new List<Topic>());
            var controller = new MessagesController(null, mockMessageServiceClient.Object, null);

            ActionResult result = controller.ListFlagged();

            Assert.IsInstanceOf<ViewResult>(result);
            //todo: consider removing the line below
            Assert.IsInstanceOf<List<Topic>>(controller.ViewData.Model);

            mockMessageServiceClient.VerifyAll();
		}

        [Test]
        public void Add_WithoutInstantiating()
        {
            const int topicId = 10;
            const string shortName = "asd";

            var mockTopicServiceClient = new Mock<ITopicsServiceClient>();
            mockTopicServiceClient
                .Setup(m => m.Get(topicId, shortName))
                .Returns(It.Is<Topic>(t => t.Id == topicId && t.ShortName == shortName));

            var controller = new MessagesController(mockTopicServiceClient.Object, null, null);
            controller.ControllerContext = new FakeControllerContext(controller, "http://localhost", null, null, new NameValueCollection(), new NameValueCollection(), new HttpCookieCollection(), ForumsControllerTest.GetSessionWithTestUser());
            controller.Url = new UrlHelper(controller.ControllerContext.RequestContext);

            ActionResult result = controller.Add(topicId, shortName, null);
            Assert.IsInstanceOf<ViewResult>(result);

            mockTopicServiceClient.VerifyAll();
        }

		/// <summary>
		/// Tests the reply
		/// </summary>
		[Test]
        public void Add_WithInstantiating()
		{
            const int topicId = 10;
            const string topicShortName = "asd";
            //const int messageId = 12;
            var message = new Message();//messageId);

            var mockTopicServiceClient = new Mock<ITopicsServiceClient>();
            mockTopicServiceClient
                .Setup(m => m.Get(topicId, topicShortName))
                .Returns(new Topic(topicId) { ShortName = topicShortName });
            var mockMessageServiceClient = new Mock<IMessagesServiceClient>();
            mockMessageServiceClient.Setup(m => m.Add(message, It.IsAny<string>()));

            var mockTopicSubscriptionClient = new Mock<ITopicsSubscriptionsServiceClient>();
            mockTopicSubscriptionClient.Setup(m => m.Remove(topicId, It.IsAny<int>(), It.IsAny<Guid>()));

            var controller = new MessagesController(
                mockTopicServiceClient.Object, mockMessageServiceClient.Object, mockTopicSubscriptionClient.Object);
			controller.ControllerContext = 
                FakeControllerContext.Create(controller, "http://localhost", ForumsControllerTest.GetSessionWithTestUser());
			controller.Url = new UrlHelper(controller.ControllerContext.RequestContext);

            controller.Add(message, topicId, topicShortName, null, null, false, null);

            mockTopicServiceClient.VerifyAll();
            mockMessageServiceClient.VerifyAll();
            mockTopicSubscriptionClient.VerifyAll();
		}

        [Test]
        public void Reply()
        {
            const int topicId = 10;
            const string topicShortName = "asd";
            const int inReplyOfId = 10;

            var mockTopicServiceClient = new Mock<ITopicsServiceClient>();
            mockTopicServiceClient
                .Setup(m => m.Get(topicId, topicShortName))
                .Returns(new Topic() { Id = topicId, ShortName = topicShortName });

            var mockTopicSubscriptionClient = new Mock<ITopicsSubscriptionsServiceClient>();
            mockTopicSubscriptionClient
                .Setup(m => m.GetSubscribed(topicId))
                .Returns(new List<User>());

            var controller = new MessagesController(mockTopicServiceClient.Object, null, mockTopicSubscriptionClient.Object);
            controller.ControllerContext = FakeControllerContext.Create(controller, "http://localhost", ForumsControllerTest.GetSessionWithTestUser());
            controller.Url = new UrlHelper(controller.ControllerContext.RequestContext);

            ActionResult result = controller.Add(topicId, topicShortName, inReplyOfId);
            Assert.That(result, Is.Not.Null.And.InstanceOf<ViewResult>());
            Assert.AreEqual("Edit", ((ViewResult)result).ViewName);
            Message modelMessage = ((ViewResult)result).Model as Message;
            Assert.NotNull(modelMessage);
            Assert.NotNull(modelMessage.InReplyOf);
            Assert.AreEqual(inReplyOfId, modelMessage.InReplyOf.Id);

            mockTopicServiceClient.VerifyAll();
            mockTopicSubscriptionClient.VerifyAll();
        }
	}
}
